#include "cface.h"

CFace::CFace(CMesh * pParent)
{
	this->setEdge1(NULL);
	this->setEdge2(NULL);
	this->setEdge3(NULL);

	this->setVertex1(NULL);
	this->setVertex2(NULL);
	this->setVertex3(NULL);

	this->m_bNormalSet = false;
	this->m_pParentMesh = pParent;
}

CEdge * CFace::getEdge1()
{
	return this->m_pEdge1;
}

CEdge * CFace::getEdge2()
{
	return this->m_pEdge2;
}

CEdge * CFace::getEdge3()
{
	return this->m_pEdge3;
}

CVertex * CFace::getVertex1()
{
	return this->m_pVertex1;
}

CVertex * CFace::getVertex2()
{
	return this->m_pVertex2;
}

CVertex * CFace::getVertex3()
{
	return this->m_pVertex3;
}

CPoint3f CFace::getNormal()
{
	return this->m_Normal;
}

bool CFace::isNormalSet()
{
	return this->m_bNormalSet;
}

CMesh * CFace::getParentMesh()
{
	return this->m_pParentMesh;
}

void CFace::setEdge1(CEdge * pEdge)
{
	this->m_pEdge1 = pEdge;
}

void CFace::setEdge2(CEdge * pEdge)
{
	this->m_pEdge2 = pEdge;
}

void CFace::setEdge3(CEdge * pEdge)
{
	this->m_pEdge3 = pEdge;
}

void CFace::setVertex1(CVertex * pVertex)
{
	this->m_pVertex1 = pVertex;
}

void CFace::setVertex2(CVertex * pVertex)
{
	this->m_pVertex2 = pVertex;
}

void CFace::setVertex3(CVertex * pVertex)
{
	this->m_pVertex3 = pVertex;
}

void CFace::computeNormal()
{
	if (this->getVertex1() != NULL && this->getVertex2() != NULL && this->getVertex3() != NULL )
	{
		CPoint3f V1 (this->getVertex2()->getX() - this->getVertex1()->getX(),
					 this->getVertex2()->getY() - this->getVertex1()->getY(),
					 this->getVertex2()->getZ() - this->getVertex1()->getZ());
		CPoint3f V2 (this->getVertex3()->getX() - this->getVertex2()->getX(),
					 this->getVertex3()->getY() - this->getVertex2()->getY(),
					 this->getVertex3()->getZ() - this->getVertex2()->getZ());
		this->m_Normal = V1.crossProduct(V2);
		this->m_Normal.normalize();
		this->m_bNormalSet = true;
	}
}

void CFace::computeEdges()
{
	if (!this->getVertex1() || !this->getVertex2() || !this->getVertex3())
	{
		qDebug() << "FAIL TO COMPUTE EDGES OF A FACE : NO VERTEX SET";
		return;
	}
	CEdge * pE1 = this->getEdge1();
	CEdge * pE2 = this->getEdge2();
	CEdge * pE3 = this->getEdge3();

	if (NULL != pE1)
	{
		pE1->getHead()->removeEdge(pE1);
		pE1->getTail()->removeEdge(pE1);
		if (pE1->getTwinEdge())
			pE1->getTwinEdge()->setTwinEdge(NULL);
		delete pE1;
	}
	if (NULL != pE2)
	{
		pE2->getHead()->removeEdge(pE2);
		pE2->getTail()->removeEdge(pE2);
		if (pE2->getTwinEdge())
			pE2->getTwinEdge()->setTwinEdge(NULL);
		delete pE2;
	}
	if (NULL != pE3)
	{
		pE3->getHead()->removeEdge(pE3);
		pE3->getTail()->removeEdge(pE3);
		if (pE3->getTwinEdge())
			pE3->getTwinEdge()->setTwinEdge(NULL);
		delete pE3;
	}

	pE1 = new CEdge();
	pE1->setFace(this);
	pE1->setHead(this->getVertex1());
	pE1->setTail(this->getVertex2());
	this->setEdge1(pE1);
	this->getVertex1()->addEdge(pE1);
        //this->getVertex2()->addEdge(pE1);

	pE2 = new CEdge();
	pE2->setFace(this);
	pE2->setHead(this->getVertex2());
	pE2->setTail(this->getVertex3());
	this->setEdge2(pE2);
	this->getVertex2()->addEdge(pE2);
        //this->getVertex3()->addEdge(pE2);

	pE3 = new CEdge();
	pE3->setFace(this);
	pE3->setHead(this->getVertex3());
	pE3->setTail(this->getVertex1());
	this->setEdge3(pE3);
	this->getVertex3()->addEdge(pE3);
        //this->getVertex1()->addEdge(pE3);

	pE1->setNextEdge(pE2);
	pE2->setNextEdge(pE3);
	pE3->setNextEdge(pE1);
}

void CFace::turnOver()
{
/*
	CVertex * pV1 = this->getVertex1();
	CVertex * pV2 = this->getVertex2();
	CEdge * pE1 = this->getEdge1();
	CEdge * pE2 = this->getEdge2();
	CEdge * pE3 = this->getEdge3();
	CEdge * pTE1 = pE1->getTwinEdge();
	CFace * pFt = pTE1->getFace();
*/
}
